/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package issr.persistence;

import issr.entity.IndiceMaster;
import issr.entity.IndiceTemp;
import issr.entity.Log;
import issr.entity.Lotto;
import issr.entity.Prodotto;
import issr.entity.Puntovendita;
import issr.entity.Ruolo;
import issr.entity.Utente;
import issr.hibernate.HibernateUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.Query;
import org.hibernate.Session;

/**
 *
 * @author Soulreaver
 */
public class Database implements IPersistenza, ILog, Serializable {

    private static Database instance;

    public static Database getInstance() {
        if (instance == null) {
            instance = new Database();
        }
        return instance;
    }

    @Override
    public Utente caricaUtente(String user, String password) {
        Utente utente = null;
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where login='" + user + "' and password='" + password + "'");
        utente = (Utente) q.uniqueResult();
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return utente;
    }
    
    @Override
    public Utente caricaTitolare(Puntovendita puntovendita) {
        Utente titolare = null;
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where ruolo='" + 2 + "' and pv='" + puntovendita.getId() + "'");
        titolare = (Utente) q.uniqueResult();
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return titolare;
    }

    @Override
    public void creaNuovoDipendente(Utente user) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public ArrayList<Utente> caricaDipendentiOrganizzazione() {
        ArrayList<Utente> listaDipendenti = new ArrayList<Utente>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where ruolo<>'" + 1 + "'");
        listaDipendenti.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaDipendenti;
    }
    
    @Override
    public ArrayList<Utente> caricaDipendentiPV(Puntovendita pv) {
        ArrayList<Utente> listaDipendenti = new ArrayList<Utente>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where pv='" + pv.getId() + "' AND ruolo>'" + 2 + "'");
        listaDipendenti.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaDipendenti;
    }
    
    @Override
    public ArrayList<Utente> caricaDipendentiPVSemplici(Puntovendita pv) {
        ArrayList<Utente> listaDipendenti = new ArrayList<Utente>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where pv='" + pv.getId() + "' AND ruolo>'" + 3 + "'");
        listaDipendenti.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaDipendenti;
    }

    @Override
    public ArrayList<Utente> caricaListaGestoriPVDisponibili() {
        ArrayList<Utente> listaDipendenti = new ArrayList<Utente>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Utente where ruolo='" + 2 + "' AND pv is null");
        listaDipendenti.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaDipendenti;
    }

    @Override
    public ArrayList<Puntovendita> caricaPuntiVendita() {
        ArrayList<Puntovendita> listaPuntiVendita = new ArrayList<Puntovendita>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Puntovendita");
        listaPuntiVendita.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaPuntiVendita;
    }

    @Override
    public void creaNuovoPuntoVendita(Utente titolare, Puntovendita puntoVendita) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(puntoVendita);
        session.saveOrUpdate(titolare);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void assegnaDipendente(Utente utente) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.update(utente);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public ArrayList<Prodotto> caricaCatalogo(Puntovendita puntovendita) {
        ArrayList<Prodotto> catalogo = new ArrayList<Prodotto>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Prodotto where pv='" + puntovendita.getId() + "'");
        catalogo.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return catalogo;
    }

    @Override
    public void inserisciLotto(Lotto lotto) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(lotto);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }
    
    @Override
    public void aggiornaContatori(Prodotto prodotto, int erogati, int immagazzinati, int restituiti, int richiesti, int scaduti) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();

        Query q1 = session.createQuery("from IndiceMaster where id='" + prodotto.getId() + "'");
        IndiceMaster im = ((IndiceMaster) q1.uniqueResult());
        im.setErogati(erogati + im.getErogati());
        im.setImmagazzinati(immagazzinati + im.getImmagazzinati());
        im.setRestituiti(restituiti + im.getRestituiti());
        im.setRichiesti(richiesti + im.getRichiesti());
        im.setScaduti(scaduti + im.getScaduti());

        Query q2 = session.createQuery("from IndiceTemp where id='" + prodotto.getId() + "'");
        IndiceTemp it = ((IndiceTemp) q2.uniqueResult());
        it.setErogati(erogati + it.getErogati());
        it.setImmagazzinati(immagazzinati + it.getImmagazzinati());
        it.setRestituiti(restituiti + it.getRestituiti());
        it.setRichiesti(richiesti + it.getRichiesti());
        it.setScaduti(scaduti + it.getScaduti());
        session.update(im);

        session.update(it);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void caricaContatori() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void aggiornaTrif(Date trif) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query qit = session.createQuery("from IndiceTemp");
        Iterator<IndiceTemp> iterate = qit.iterate();
        while (iterate.hasNext()) {
            IndiceTemp tmp = iterate.next();
            tmp.resettaContatori();
            tmp.setTrif(trif);
            session.update(tmp);
        }
//        qit.executeUpdate();
//        qit..setParameter("trif", trif);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void creaProdotto(Prodotto prodotto, IndiceMaster imaster, IndiceTemp itemp) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(prodotto);
        session.save(imaster);
        session.save(itemp);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void aggiornaFatture() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void aggiungiEntry(Utente user, String entry) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(new Log(user, new Date(), entry));
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void aggiungiEntry(Utente user, Puntovendita pv, String entry) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.save(new Log(user, pv, new Date(), entry));
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public ArrayList<Log> caricaInteroLog() {
        ArrayList<Log> logEntries = new ArrayList<Log>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Log");
        logEntries.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return logEntries;
    }

    @Override
    public ArrayList<Log> caricaLog(Puntovendita pv) {
        ArrayList<Log> logEntries = new ArrayList<Log>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Log where pv='" + pv.getId() + "'");
        logEntries.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return logEntries;
    }

    @Override
    public ArrayList<Ruolo> caricaRuoli() {
        ArrayList<Ruolo> listaRuoli = new ArrayList<Ruolo>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Ruolo where id<>'" + 1 + "'");
        listaRuoli.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaRuoli;
    }

    @Override
    public void generaPassword(Utente utente) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.saveOrUpdate(utente);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public ArrayList<Ruolo> caricaRuoliPV() {
        ArrayList<Ruolo> listaRuoli = new ArrayList<Ruolo>();
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Ruolo where id<>'" + 1 + "' AND id<>'" + 2 + "'");
        listaRuoli.addAll(q.list());
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return listaRuoli;
    }

    @Override
    public Lotto caricaLotto(int codiceAbarre) {
        Lotto lotto;
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query q = session.createQuery("from Lotto where gs1BarCode='" + codiceAbarre + "'");
        lotto = (Lotto) q.uniqueResult();
        session.getTransaction().commit();
        HibernateUtil.closeSession();
        return lotto;

    }

    @Override
    public void aggiornaLotto(Lotto lotto) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.saveOrUpdate(lotto);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }

    @Override
    public void rimuoviLotto(Lotto lotto) {
        Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.delete(lotto);
        session.getTransaction().commit();
        HibernateUtil.closeSession();
    }
}
